package com.dhcc.bpm.modules.orga.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.annotation.Log;
import com.dhcc.bpm.common.config.AppEmailConfig;
import com.dhcc.bpm.common.constant.Const;
import com.dhcc.bpm.common.enums.BusinessType;
import com.dhcc.bpm.common.redisMessage.RedisMessageSender;
import com.dhcc.bpm.common.utils.*;
import com.dhcc.bpm.modules.api.service.IProductApiService;
import com.dhcc.bpm.modules.api.vo.ApiVO;
import com.dhcc.bpm.modules.api.vo.ProductApiVO;
import com.dhcc.bpm.modules.orga.entity.App;
import com.dhcc.bpm.modules.orga.entity.AppApi;
import com.dhcc.bpm.modules.orga.service.IAppApiService;
import com.dhcc.bpm.modules.orga.service.IAppService;
import com.dhcc.bpm.modules.orga.vo.AppApiVO;
import com.dhcc.bpm.modules.system.service.IDictService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName AppApiController
 * @Description 应用API关系表 控制器
 * @Author daina
 * @Date 2020/2/24 19:25
 * @Version V1.0
 * @Copyright: 2020 东华软件 . All rights reserved.
 */
@RestController
@AllArgsConstructor
@NoArgsConstructor
@RequestMapping("bpm-system/appapi")
@Api(value = "应用API关系表", tags = "应用API关系表接口")
public class AppApiController extends BladeController {

	private static final Logger log = LoggerFactory.getLogger(AppApiController.class);
	@Autowired
	private IAppApiService appApiService;
	@Autowired
	private IProductApiService productApiService;
	@Autowired
	private IAppService appService;
	@Autowired
	private IDictService dictService;
	@Autowired
	private EmailUtils emailUtils;
	@Autowired
	private AppEmailConfig appEmailConfig;
	@Autowired
	private RedisMessageSender redisMessageSender;
	@Autowired
	private TokenStore tokenStore;

	//	@Value("${spring.mail.web-front}")
	//	private String webLocation;
	@Value("${bpm.approval.isSendMail}")
	private boolean isSendFlag;

	/**
	 * @Description 详情
	 * @Author daina
	 * @Date 10:37 2020/2/25
	 * @param appApi
	 * @return org.springblade.core.tool.api.R<com.dhcc.bpm.modules.orga.entity.AppApi>
	 **/
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "应用API关系表 详情", notes = "传入appApi")
	@ApiLog("应用API关系表 详情")
	@Log(title = "应用API关系表 详情", businessType = BusinessType.SELECT)
	public R<AppApi> detail(AppApi appApi) {
		AppApi detail = appApiService.getOne(Condition.getQueryWrapper(appApi));
		return R.data(detail);
	}
	/**
	 * @Description api下线 查询已下线产品下面的api列表信息
	 * @Author daina
	 * @Date 15:59 2020/4/26
	 * @param appApi
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.orga.vo.AppApiVO>>
	 **/
	@GetMapping("/listApiByApiId")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入appApi")
	@ApiLog("查询api 已下线产品")
	@Log(title = "查询api 已下线产品", businessType = BusinessType.SELECT)
	public R<IPage<AppApiVO>> listApiByApiId(AppApiVO appApi, Query query) {
		IPage<AppApiVO> pages = appApiService.listApiByApiId(Condition.getPage(query), appApi);
		return R.data(pages);
	}

	@GetMapping("/appapioffline")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入appApi")
	@ApiLog("api下线前查询")
	@Log(title = "api下线前查询", businessType = BusinessType.SELECT)
	public R<String> appapioffline(ProductApiVO productApi, Query query) {
		// status:下线不同状态的标志 a: 直接下线 ; b:提醒：改API已被应用产品关联，请先将应用产品下线; c:有渠道进行订阅关联该API的应用产品，则进行展示订阅该应用产品的所有渠道; d:无渠道进行订阅关联该API的应用产品，直接下线
		String status = "";
		log.info(productApi.getApiId().toString());
		List<ProductApiVO> lists = productApiService.listApiRelate(productApi);
		//
		if(lists.size() <= 0){
			//a 没数据说明应用产品里没有关联这个API 直接下线
			status = "a";
		}else{
			for(ProductApiVO productApivo :lists){
				//  productStatus：产品状态   6：已下线
				String productStatus = "6";
				if(!productApivo.getProStatus().equals(productStatus)){
					// b 如果应用产品里有关联这个API，但是存在应用产品没有下线，则直接提醒：改API已被应用产品关联，请先将应用产品下线
					status = "b";
					return R.data(status);
				}
				// 如果应用产品里有关联这个API，应用产品全部下线，有渠道进行订阅关联该API的应用产品，则进行展示订阅该应用产品的所有渠道
			}
			//查询 有渠道进行订阅关联该API的应用产品，则进行展示订阅该应用产品的所有渠道
			AppApiVO appApi = new AppApiVO();
			appApi.setId(productApi.getApiId());
			IPage<AppApiVO> pages = appApiService.listApiByApiId(Condition.getPage(query), appApi);
			List<AppApiVO> appApiLists = pages.getRecords();
			if(appApiLists.size()>0){
				// c 有渠道进行订阅关联该API的应用产品，则进行展示订阅该应用产品的所有渠道
				status = "c";
			}else{
				// d:无渠道进行订阅关联该API的应用产品，直接下线
				status = "d";
			}
		}
		return R.data(status);
	}
	/**
	 * @Description api下线前通知渠道联系人
	 * @Author daina
	 * @Date 9:18 2020/4/27
	 * @param appApi
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.orga.vo.AppApiVO>>
	 **/
	@GetMapping("/noticeApp")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入appApi")
	@ApiLog("api下线调用")
	@Log(title = "查询api 已下线产品", businessType = BusinessType.OTHER)
	public R noticeApp(AppApiVO appApi, Query query) {
		boolean bool = true;
		String nowDate = DateUtils.dateTimeNow();
		//获取下线时间
		int days = 3;
		Calendar calendar2 = Calendar.getInstance();
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
		calendar2.add(Calendar.DATE, days);
		String offLineDate = sdf2.format(calendar2.getTime());

		//获取需要通知的app
		App app = appService.getById(appApi.getOpcAppId().toString());
		String mailTitle = appEmailConfig.getTitle() + "API下线通知";
		try {
			String dateTime = DateUtils.getSystemDateStringY2NO();
			dateTime = dateTime.substring(0,16);
			String newMailContent = AES2Util.encrypt(app.getPrpEmail(), dateTime);
			JSONObject res = new JSONObject();
			res.put("mc",newMailContent);
			res.put("nd",dateTime);
			res.put("code","10034");
			String result = RSAUtil.encrypt(res.toString(),RSAUtil.getPublicKey(Const.webPublicKey));
			String  webLocation= "http://127.0.0.1:8887";
			List<String> userList = new LinkedList<>();
//			String content = "尊敬的用户，您好！\r\n" + "您订阅的API：" + appApi.getApiName() + " 将在三天后"+ offLineDate
//					+"下线，请登录OPENAPI开放门户网站查看具体内容！请点击链接进行密码重置：" + webLocation+"/forward?auth=" +result;

			String content = "尊敬的用户，您好！\r\n" + "您订阅的API：" + appApi.getApiName() + " 将在三天后"+ offLineDate
					+"下线! 请点击下方确认下线按钮进行确认：";
			bool = emailUtils.sendConfirmEmail( mailTitle, app.getPrpEmail(), mailTitle, content,webLocation+"/#/user/appconfirm/"+appApi.getId());
			if(bool){
				AppApi opcAppApi = appApiService.getById(appApi.getId().toString());
				// 状态改为已通知
				opcAppApi.setNoticeStatus("2");
				opcAppApi.setNoticeTime(DateUtils.getNowDate());
				bool = appApiService.saveOrUpdate(opcAppApi);
			}
		}catch (Exception e){
			log.error("异常信息：",e);
			return R.status(false);
		} finally {

		}
		return R.status(bool);
	}
	/**
	 * @Description app确认已接到通知
	 * @Author daina
	 * @Date 15:26 2020/4/27
	 * @param id
	 * @return org.springblade.core.tool.api.R
	 **/
	@GetMapping("/confirm")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "app确认已接到通知", notes = "传入appApi")
	@ApiLog("app确认已接到通知")
	@Log(title = "app确认已接到通知", businessType = BusinessType.UPDATE)

	public R confirm(Long id ) {
		AppApiVO appApi = new AppApiVO();
		appApi.setId(id);
		appApi.setConfirmStatus("2");
		boolean bool = appApiService.updateById(appApi);
		return R.status(bool);
	}
	/**
	 * @Description 分页 应用API关系表
	 * @Author daina
	 * @Date 10:37 2020/2/25
	 * @param appApi
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.orga.entity.AppApi>>
	 **/
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入appApi")
	@ApiLog("应用API关系表 分页")
	@Log(title = "应用API关系表 分页", businessType = BusinessType.SELECT)
	public R<IPage<AppApi>> list(AppApi appApi, Query query) {
		IPage<AppApi> pages = appApiService.page(Condition.getPage(query), Condition.getQueryWrapper(appApi));
		return R.data(pages);
	}

	/**
	 * @Description 应用API关系表
	 * @Author daina
	 * @Date 10:37 2020/2/25
	 * @param appApi
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.orga.vo.AppApiVO>>
	 **/
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入appApi")
	@ApiLog("应用API关系表 分页")
	@Log(title = "应用API关系表 分页", businessType = BusinessType.SELECT)
	public R<IPage<AppApiVO>> page(AppApiVO appApi, Query query) {
		IPage<AppApiVO> pages = appApiService.selectAppApiPage(Condition.getPage(query), appApi);
		return R.data(pages);
	}

	/**
	 * @Description 新增应用API关系表
	 * @Author daina
	 * @Date 10:37 2020/2/25
	 * @param appApi
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入appApi")
	@ApiLog("应用API关系表 新增")
	@Log(title = "应用API关系表 新增", businessType = BusinessType.INSERT)
	public R save(@Valid @RequestBody AppApi appApi) {
		return R.status(appApiService.save(appApi));
	}

	/**
	 * @Description  修改 应用API关系表
	 * @Author daina
	 * @Date 10:37 2020/2/25
	 * @param appApi
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入appApi")
	@ApiLog("应用API关系表 修改")
	@Log(title = "应用API关系表 修改", businessType = BusinessType.UPDATE)
	public R update(@Valid @RequestBody AppApiVO appApi) {
		boolean bool = appApiService.updateById(appApi);
		if(appApi.getStatusFlag() != null && appApi.getStatusFlag().equals("1")){
			//刷新token
			Collection<OAuth2AccessToken> findTokensByClientId = tokenStore.findTokensByClientId(appApi.getAppId());
			findTokensByClientId.forEach(p -> redisMessageSender.sendMessageToChannel("TOKEN", tokenStore.readAccessToken(p.getValue()).getValue()));
		}
		return R.status(bool);
	}

	/**
	 * @Description 新增或修改 应用API关系表
	 * @Author daina
	 * @Date 10:37 2020/2/25
	 * @param appApi
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入appApi")
	@ApiLog("应用API关系表 新增或修改")
	@Log(title = "应用API关系表 新增或修改", businessType = BusinessType.INSERT)
	public R submit(@Valid @RequestBody AppApi appApi) {
		return R.status(appApiService.saveOrUpdate(appApi));
	}


	/**
	 * @Description 删除 应用API关系表
	 * @Author daina
	 * @Date 10:38 2020/2/25
	 * @param ids
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/remove")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "删除", notes = "传入ids")
	@ApiLog("应用API关系表 删除")
	@Log(title = "应用API关系表 删除", businessType = BusinessType.DELETE)
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(appApiService.removeByIds(Func.toLongList(ids)));
	}

	/**
	 * @param appApi
	 * @return org.springblade.core.tool.api.R
	 * @Description 查询app订阅的api
	 * @Author daina
	 * @Date 14:30 2020/2/25
	 **/
	@GetMapping("/getApiListByProductId")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "查询app订阅的api", notes = "传入AppApi")
	@ApiLog("查询app订阅的api ")
	@Log(title = "查询app订阅的api", businessType = BusinessType.SELECT)
	public ResultAPI getApiListByProductId(AppApi appApi) {
		Map<String, Object> map = new HashMap<>();
		List<ApiVO> apiVOList = new ArrayList<>();
		//List<com.dhcc.bpm.modules.api.entity.Api> list = appApiService.getApiListByProductId(appApi.getOpcAppId(), appApi.getOpcProductId());
		List<ApiVO> list = appApiService.getApiListByProductId(appApi.getOpcAppId(), appApi.getOpcProductId());
		if (list.size()>0){
			list.forEach(data->{
				//访问协议描述
				data.setAccessProtocolDesc(dictService.getValue("gateway_access_protocol", String.valueOf(data.getAccessProtocol())));
				//是否需要回调地址描述
				data.setIsRequireCallbackUrlDesc(dictService.getValue("is_require_callback_url", String.valueOf(data.getIsRequireCallbackUrl())));
				//安全认证类型描述
				data.setSafeTypeDesc(dictService.getValue("safe_type", String.valueOf(data.getSafeType())));
				//报文类型描述
				data.setMessageTypeDesc(dictService.getValue("gateway_message_type", String.valueOf(data.getMessageType())));
				//权限等级描述
				data.setPrivilegeLevelDesc(dictService.getValue("privilege_level", String.valueOf(data.getPrivilegeLevel())));
				//是否收费描述
				data.setIsCostDesc(dictService.getValue("is_cost", String.valueOf(data.getIsCost())));
				apiVOList.add(data);
			});
		}
		map.put("apiList", apiVOList);
		return ResultAPI.success(map);
	}


	/**
	 * @Description 修改关联表信息
	 * @Author wjh
	 * @Date 2020-10-30 14:32:11
	 **/
	@PostMapping("/updateAppApi")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入appApi")
	@ApiLog("修改关联表信息")
	@Log(title = "修改关联表信息", businessType = BusinessType.UPDATE)
	public R updateAppApi(@RequestBody AppApi appApi) {

		return R.status(appApiService.updateAppApi(appApi)>0);
	}
}
